from flask import current_app

import json

from app.models.bo.hanfan.hanfan_reason_input_bo import HanfanReasonInputBO
from app.models.bo.hanfan.hanfan_reason_status_bo import HanFanReasonStatusBO
from app.models.po.hanfan.hanfan_new_predict_po import HanfanNewPredictPO
from app.services.models.const import hanfan_rule_params, NORMAL_CODE, DATA_ERROR_CODE, LOW_CODE, HIGH_CODE
from app.services.models.pickle_model import PickleModel
from interval3 import Interval


class HanfanReasonModel(PickleModel):
    def __init__(self):
        super().__init__(model_name="hanfan_reason_model")

    def process(self, hanfan_new_predict_bo: HanfanNewPredictPO):
        try:
            hanfan_reason_status_bo = HanFanReasonStatusBO()
            for param in hanfan_rule_params:
                hanfan_reason_status_bo.__setattr__(param,
                                                    self.get_param_status(
                                                        hanfan_new_predict_bo.CG_LT_GL_GL04_Yuanranliao_Ore_V2O5,
                                                        param,
                                                        hanfan_new_predict_bo.__getattribute__(param),
                                                    ))
            return hanfan_reason_status_bo
        except Exception as e:
            current_app.logger.error(e, exc_info=1)

    def get_reason_scope(self, hanfan_reason_input_bo: HanfanReasonInputBO):

        return {param: self.get_param_scope(hanfan_reason_input_bo.CG_LT_GL_GL04_Yuanranliao_Ore_V2O5,
                                            param) for param in hanfan_rule_params}

    def get_param_interval(self, Ore_V2O5, param, param_value):
        try:
            p = None
            rule_dict = self.model_instance[param]
            for key in rule_dict.keys():
                if Ore_V2O5 in key:
                    p = rule_dict[key]
            # interval 区间
            if param_value is None:
                return None
            return [p.lower_bound,p.upper_bound]
        except Exception as e:
            current_app.logger.error("param " + param + " cause exception.", exc_info=1)
            return DATA_ERROR_CODE

    def get_param_status(self, Ore_V2O5, param, param_value):
        """
        获取参数状态
        :param Ore_V2O5:
        :param param:
        :param param_value:
        :return:
        """
        try:
            p = None
            rule_dict = self.model_instance[param]
            for key in rule_dict.keys():
                if Ore_V2O5 in key:
                    p = rule_dict[key]
            # interval 区间
            if p is None:
                return DATA_ERROR_CODE
            if param_value is None:
                return DATA_ERROR_CODE
            if param_value in p:
                return NORMAL_CODE
            elif Interval(upper_bound=param_value) < p:
                return HIGH_CODE
            elif Interval(lower_bound=param_value) > p:
                return LOW_CODE
        except Exception as e:
            current_app.logger.error("param " + param + " cause exception.", exc_info=1)
            return DATA_ERROR_CODE

    def get_param_scope(self, Ore_V2O5, param):
        """
        获取参数的范围
        :param Ore_V2O5:
        :param param:
        :return:
        """
        try:
            rule_dict = self.model_instance[param]
            p = None
            for key in rule_dict.keys():
                if Ore_V2O5 in key:
                    p = rule_dict[key]
                    lower = p.lower_bound
                    upper = p.upper_bound
                    return "[{},{}]".format(round(lower, 3), round(upper, 3))

        except Exception as e:
            current_app.logger.error("param " + param + " cause exception.", exc_info=1)
            return ""

    def get_best_value(self,Ore_V2O5):
        rule_dict = self.model_instance["best_value"]
        for key in rule_dict.keys():
            if Ore_V2O5 in key:
                p = rule_dict[key]
                return p



# 用导出module的方法创建单例
hanfan_reason_model = HanfanReasonModel()
